package view;

import model.User;
import service.UserService;
import javax.swing.*;
import java.awt.*;
import javax.swing.border.EmptyBorder;

//陈甜


// ChangePasswordDialog类继承自JDialog，用于创建一个修改用户密码的对话框界面
public class ChangePasswordDialog extends JDialog {
    // 当前要修改密码的用户对象
    private User currentUser;
    // 用户服务类对象，用于处理与用户相关的业务逻辑，比如验证密码、更新密码等操作
    private UserService userService;
    // 用于输入旧密码的密码框
    private JPasswordField oldPasswordField;
    // 用于输入新密码的密码框
    private JPasswordField newPasswordField;
    // 用于再次输入新密码（确认新密码）的密码框
    private JPasswordField confirmPasswordField;

    // 构造函数，用于初始化修改密码对话框
    // 参数parent表示父窗口（通常是主界面所在的JFrame），user表示当前要修改密码的用户对象
    public ChangePasswordDialog(JFrame parent, User user) {
        // 调用父类JDialog的构造函数，设置对话框标题为"修改密码"，并设置为模态对话框（即显示时阻塞其他窗口操作）
        super(parent, "修改密码", true);
        this.currentUser = user;
        // 创建UserService实例，用于后续调用相关业务方法
        this.userService = new UserService();
        // 初始化对话框的各个组件
        initComponents();
    }

    // 初始化对话框的各个组件，包括布局、添加文本标签、密码框、按钮等，并设置相应的事件监听
    private void initComponents() {
        // 设置对话框的大小为宽350像素，高250像素
        setSize(350, 250);
        // 设置对话框相对于所有者窗口（即父窗口）居中显示
        setLocationRelativeTo(getOwner());
        // 设置对话框不可调整大小
        setResizable(false);

        // 创建主面板，使用GridBagLayout布局管理器，这种布局可以更灵活地控制组件的位置和大小
        JPanel mainPanel = new JPanel(new GridBagLayout());
        // 为主面板设置边框，四周都留出20像素的空白边距
        mainPanel.setBorder(new EmptyBorder(20, 20, 20, 20));
        // 创建GridBagConstraints对象，用于设置组件在GridBagLayout布局中的约束条件
        GridBagConstraints gbc = new GridBagConstraints();
        // 设置组件之间的内边距，上下左右都为5像素
        gbc.insets = new Insets(5, 5, 5, 5);
        // 设置组件在水平方向上填充可用空间（使得组件能占满水平方向的空间）
        gbc.fill = GridBagConstraints.HORIZONTAL;

        // 旧密码相关组件添加
        // 设置组件在GridBagLayout布局中的横坐标位置为0，纵坐标位置为0
        gbc.gridx = 0;
        gbc.gridy = 0;
        // 在主面板上添加一个显示"旧密码："文本的JLabel标签，按照上面设置的约束条件进行布局
        mainPanel.add(new JLabel("旧密码："), gbc);

        gbc.gridx = 1;
        // 创建一个可输入20个字符长度的密码框，用于输入旧密码
        oldPasswordField = new JPasswordField(20);
        // 将旧密码框添加到主面板上，按照当前设置的约束条件布局
        mainPanel.add(oldPasswordField, gbc);

        // 新密码相关组件添加
        gbc.gridx = 0;
        gbc.gridy = 1;
        // 在主面板上添加一个显示"新密码："文本的JLabel标签，按照约束条件布局
        mainPanel.add(new JLabel("新密码："), gbc);

        gbc.gridx = 1;
        // 创建一个可输入20个字符长度的密码框，用于输入新密码
        newPasswordField = new JPasswordField(20);
        // 将新密码框添加到主面板上，按照当前约束条件布局
        mainPanel.add(newPasswordField, gbc);

        // 确认新密码相关组件添加
        gbc.gridx = 0;
        gbc.gridy = 2;
        // 在主面板上添加一个显示"确认新密码："文本的JLabel标签，按照约束条件布局
        mainPanel.add(new JLabel("确认新密码："), gbc);

        gbc.gridx = 1;
        // 创建一个可输入20个字符长度的密码框，用于再次输入新密码（确认新密码）
        confirmPasswordField = new JPasswordField(20);
        // 将确认新密码框添加到主面板上，按照当前约束条件布局
        mainPanel.add(confirmPasswordField, gbc);

        // 按钮面板相关操作
        // 创建一个新的面板，用于放置确认和取消按钮，默认使用流式布局（FlowLayout）
        JPanel buttonPanel = new JPanel();
        // 创建一个"确认"按钮
        JButton confirmButton = new JButton("确认");
        // 创建一个"取消"按钮
        JButton cancelButton = new JButton("取消");

        // 设置"确认"按钮的首选大小为宽80像素，高30像素，这样按钮在布局中会尽量按照这个尺寸显示
        confirmButton.setPreferredSize(new Dimension(80, 30));
        // 设置"取消"按钮的首选大小为宽80像素，高30像素
        cancelButton.setPreferredSize(new Dimension(80, 30));

        // 将"确认"按钮添加到按钮面板中
        buttonPanel.add(confirmButton);
        // 将"取消"按钮添加到按钮面板中
        buttonPanel.add(cancelButton);

        gbc.gridx = 0;
        gbc.gridy = 3;
        // 设置组件在GridBagLayout布局中占据的网格宽度为2（即横跨两列）
        gbc.gridwidth = 2;
        // 设置组件的内边距，上方为15像素，左右和下方为5像素
        gbc.insets = new Insets(15, 5, 5, 5);
        // 将按钮面板添加到主面板上，按照当前设置的约束条件布局
        mainPanel.add(buttonPanel, gbc);

        // 为"确认"按钮添加动作监听器，当按钮被点击时，会调用handleChangePassword方法来处理密码修改逻辑
        confirmButton.addActionListener(e -> handleChangePassword());
        // 为"取消"按钮添加动作监听器，当按钮被点击时，会关闭当前对话框（调用dispose方法）
        cancelButton.addActionListener(e -> dispose());

        // 设置当在对话框中按下回车键时，默认触发的按钮为"确认"按钮
        getRootPane().setDefaultButton(confirmButton);

        // 将主面板添加到对话框中，作为对话框的主要内容显示区域
        add(mainPanel);
    }

    // 处理密码修改的具体逻辑方法
    private void handleChangePassword() {
        // 获取旧密码框中输入的密码内容，并转换为字符串（JPasswordField默认返回字符数组）
        String oldPassword = new String(oldPasswordField.getPassword());
        // 获取新密码框中输入的密码内容，并转换为字符串
        String newPassword = new String(newPasswordField.getPassword());
        // 获取确认新密码框中输入的密码内容，并转换为字符串
        String confirmPassword = new String(confirmPasswordField.getPassword());

        // 验证输入合法性
        // 如果旧密码、新密码或确认新密码有任何一个为空字符串，说明用户没有填写完整，弹出错误提示对话框并返回，不进行后续操作
        if (oldPassword.isEmpty() || newPassword.isEmpty() || confirmPassword.isEmpty()) {
            JOptionPane.showMessageDialog(this, "请填写所有密码字段！", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        // 验证两次输入的新密码是否一致，如果不一致，弹出错误提示对话框，清空新密码和确认新密码框内容，并让新密码框获取焦点，方便用户重新输入，然后返回，不进行后续操作
        if (!newPassword.equals(confirmPassword)) {
            JOptionPane.showMessageDialog(this, "两次输入的新密码不一致！", "错误", JOptionPane.ERROR_MESSAGE);
            newPasswordField.setText("");
            confirmPasswordField.setText("");
            newPasswordField.requestFocus();
            return;
        }

        // 调用userService的verifyPassword方法验证旧密码是否正确，传入当前用户的用户名和输入的旧密码
        // 如果验证失败，说明旧密码错误，弹出错误提示对话框，清空旧密码框内容，并让旧密码框获取焦点，方便用户重新输入，然后返回，不进行后续操作
        if (!userService.verifyPassword(currentUser.getUsername(), oldPassword)) {
            JOptionPane.showMessageDialog(this, "旧密码错误！", "错误", JOptionPane.ERROR_MESSAGE);
            oldPasswordField.setText("");
            oldPasswordField.requestFocus();
            return;
        }

        // 调用userService的updatePassword方法尝试更新密码，传入当前用户的ID和新密码
        // 如果更新成功，弹出密码修改成功的提示对话框，并关闭当前对话框
        if (userService.updatePassword(currentUser.getId(), newPassword)) {
            JOptionPane.showMessageDialog(this, "密码修改成功！", "成功", JOptionPane.INFORMATION_MESSAGE);
            dispose();
        } else {
            // 如果更新失败，弹出密码修改失败的提示对话框，提示用户重试
            JOptionPane.showMessageDialog(this, "密码修改失败，请重试！", "错误", JOptionPane.ERROR_MESSAGE);
        }
    }
}